﻿/* ULS Logging Class
 * Steven Van de Craen
 * 
 * This class uses Log4Net for logging.
 * It uses RunWithElevatedPrivileges to run as System Account in order to be able to write to Registry (Event Log) and such.
 * This only works from a web context. If run from a non-web context (custom app, STSADM) it runs as the current user. 
 */
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using log4net;
using log4net.Config;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;

namespace Ventigrate.Shared.ExternalMembership.Internal
{
    public class ULS : ILog
    {
        const string THREADEDLOGGER_KEY = "LOGGER";
        const string DEFAULTLOGGER_CONFIGXML =
            @"<log4net>
                <appender name=""DefaultAppender"" type=""log4net.Appender.EventLogAppender"">
                    <applicationName value=""log4net"" />
                    <layout type=""log4net.Layout.PatternLayout"">
                        <conversionPattern value=""[%date][%logger]: %message %newline "" />
                    </layout>
                </appender>
                <root>
                    <level value=""DEBUG"" />
                    <appender-ref ref=""DefaultAppender"" />
                </root>
            </log4net>";

        private ILog _log = null;

        #region Constructors
        private ULS()
            : this(typeof(ULS))
        { }

        private ULS(Type type)
        {
            _log = LogManager.GetLogger(type.FullName);
        }

        static ULS()
        {
            FileInfo fi = new FileInfo(SPUtility.GetVersionedGenericSetupPath(@"CONFIG\log4net\config.xml", 15));
            if (!fi.Exists)
            {
                using (MemoryStream ms = new MemoryStream(Encoding.Default.GetBytes(DEFAULTLOGGER_CONFIGXML)))
                {
                    XmlConfigurator.Configure(ms);
                }

                ULS.Log.WarnFormat("Could not find log4net configuration file '{0}'. Loading the default configuration settings. Add the configuration file and restart any processes affected by this.", fi.FullName);
            }
            else
            {
                XmlConfigurator.ConfigureAndWatch(fi);
            }
        }
        #endregion

        public static ILog Log
        {
            get
            {
                // If thread's logger not initialized then make it so with the Calling Type's name as Logger Source
                if (ThreadContext.Properties[THREADEDLOGGER_KEY] == null)
                    ThreadContext.Properties[THREADEDLOGGER_KEY] = new ULS(new StackFrame(1, false).GetMethod().DeclaringType);

                return (ILog)ThreadContext.Properties[THREADEDLOGGER_KEY];
            }
        }

        #region ILog Members

        public void Debug(object message, Exception exception)
        {
            if (IsDebugEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.Debug(message, exception);
                    }
                );
            }
        }

        public void Debug(object message)
        {
            if (IsDebugEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.Debug(message);
                    }
                );
            }
        }

        public void DebugFormat(IFormatProvider provider, string format, params object[] args)
        {
            if (IsDebugEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.DebugFormat(provider, format, args);
                    }
                );
            }
        }

        public void DebugFormat(string format, object arg0, object arg1, object arg2)
        {
            if (IsDebugEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.DebugFormat(format, arg0, arg1, arg2);
                    }
                );
            }
        }

        public void DebugFormat(string format, object arg0, object arg1)
        {
            if (IsDebugEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.DebugFormat(format, arg0, arg1);
                    }
                );
            }
        }

        public void DebugFormat(string format, object arg0)
        {
            if (IsDebugEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.DebugFormat(format, arg0);
                    }
                );
            }
        }

        public void DebugFormat(string format, params object[] args)
        {
            if (IsDebugEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.DebugFormat(format, args);
                    }
                );
            }
        }

        public void Error(object message, Exception exception)
        {
            if (IsErrorEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.Error(message, exception);
                    }
                );
            }
        }

        public void Error(object message)
        {
            if (IsErrorEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.Error(message);
                    }
                );
            }
        }

        public void ErrorFormat(IFormatProvider provider, string format, params object[] args)
        {
            if (IsErrorEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.ErrorFormat(provider, format, args);
                    }
                );
            }
        }

        public void ErrorFormat(string format, object arg0, object arg1, object arg2)
        {
            if (IsErrorEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.ErrorFormat(format, arg0, arg1, arg2);
                    }
                );
            }
        }

        public void ErrorFormat(string format, object arg0, object arg1)
        {
            if (IsErrorEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.ErrorFormat(format, arg0, arg1);
                    }
                );
            }
        }

        public void ErrorFormat(string format, object arg0)
        {
            if (IsErrorEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.ErrorFormat(format, arg0);
                    }
                );
            }
        }

        public void ErrorFormat(string format, params object[] args)
        {
            if (IsErrorEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.ErrorFormat(format, args);
                    }
                );
            }
        }

        public void Fatal(object message, Exception exception)
        {
            if (IsFatalEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.Fatal(message, exception);
                    }
                );
            }
        }

        public void Fatal(object message)
        {
            if (IsFatalEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.Fatal(message);
                    }
                );
            }
        }

        public void FatalFormat(IFormatProvider provider, string format, params object[] args)
        {
            if (IsFatalEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.FatalFormat(provider, format, args);
                    }
                );
            }
        }

        public void FatalFormat(string format, object arg0, object arg1, object arg2)
        {
            if (IsFatalEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.FatalFormat(format, arg0, arg1, arg2);
                    }
                );
            }
        }

        public void FatalFormat(string format, object arg0, object arg1)
        {
            if (IsFatalEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.FatalFormat(format, arg0, arg1);
                    }
                );
            }
        }

        public void FatalFormat(string format, object arg0)
        {
            if (IsFatalEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.FatalFormat(format, arg0);
                    }
                );
            }
        }

        public void FatalFormat(string format, params object[] args)
        {
            if (IsFatalEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.FatalFormat(format, args);
                    }
                );
            }
        }

        public void Info(object message, Exception exception)
        {
            if (IsInfoEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.Info(message, exception);
                    }
                );
            }
        }

        public void Info(object message)
        {
            if (IsInfoEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.Info(message);
                    }
                );
            }
        }

        public void InfoFormat(IFormatProvider provider, string format, params object[] args)
        {
            if (IsInfoEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.InfoFormat(provider, format, args);
                    }
                );
            }
        }

        public void InfoFormat(string format, object arg0, object arg1, object arg2)
        {
            if (IsInfoEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.InfoFormat(format, arg0, arg1, arg2);
                    }
                );
            }
        }

        public void InfoFormat(string format, object arg0, object arg1)
        {
            if (IsInfoEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.InfoFormat(format, arg0, arg1);
                    }
                );
            }
        }

        public void InfoFormat(string format, object arg0)
        {
            if (IsInfoEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.InfoFormat(format, arg0);
                    }
                );
            }
        }

        public void InfoFormat(string format, params object[] args)
        {
            if (IsInfoEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.InfoFormat(format, args);
                    }
                );
            }
        }

        public bool IsDebugEnabled
        {
            get { return _log.IsDebugEnabled; }
        }

        public bool IsErrorEnabled
        {
            get { return _log.IsErrorEnabled; }
        }

        public bool IsFatalEnabled
        {
            get { return _log.IsFatalEnabled; }
        }

        public bool IsInfoEnabled
        {
            get { return _log.IsInfoEnabled; }
        }

        public bool IsWarnEnabled
        {
            get { return _log.IsWarnEnabled; }
        }

        public void Warn(object message, Exception exception)
        {
            if (IsWarnEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.Warn(message, exception);
                    }
                );
            }
        }

        public void Warn(object message)
        {
            if (IsWarnEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.Warn(message);
                    }
                );
            }
        }

        public void WarnFormat(IFormatProvider provider, string format, params object[] args)
        {
            if (IsWarnEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.WarnFormat(provider, format, args);
                    }
                );
            }
        }

        public void WarnFormat(string format, object arg0, object arg1, object arg2)
        {
            if (IsWarnEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.WarnFormat(format, arg0, arg1, arg2);
                    }
                );
            }
        }

        public void WarnFormat(string format, object arg0, object arg1)
        {
            if (IsWarnEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.WarnFormat(format, arg0, arg1);
                    }
                );
            }
        }

        public void WarnFormat(string format, object arg0)
        {
            if (IsWarnEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.WarnFormat(format, arg0);
                    }
                );
            }
        }

        public void WarnFormat(string format, params object[] args)
        {
            if (IsWarnEnabled)
            {
                SPSecurity.RunWithElevatedPrivileges
                (
                    delegate
                    {
                        _log.WarnFormat(format, args);
                    }
                );
            }
        }

        #endregion

        #region ILoggerWrapper Members

        public log4net.Core.ILogger Logger
        {
            get { throw new NotImplementedException(); }
        }

        #endregion
    }
}